/**
 * Created on May 11, 2007
 */
package x.java.lang;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;

import jvs.vfs.FileSystem;
import x.java.io.File;

/**
 * @author qiangli
 * 
 */
public class Process extends java.lang.Process implements Runnable {

	private InputStream err = null;

	private InputStream in = null;

	private OutputStream out = null;

	private String[] cmdarray = null;

	private String[] envp = null;

	private File cwd = null;

	protected String className;

	protected String[] args;

	/**
	 * @param cmdarray
	 * @param envp
	 * @param dir
	 */
	public Process(String[] cmdarray, String[] envp, File dir) {
		this.cmdarray = cmdarray;
		this.envp = envp;
		this.cwd = dir;
		//
		className = cmdarray[0];
		//debug(className);
		args = new String[cmdarray.length - 1];
		System.arraycopy(cmdarray, 1, args, 0, args.length);
	}

	private Class<?> loadClass() throws ClassNotFoundException {
		// TODO instropect, create pipes and set in,out,err
		// TODO register with System class to track process/thread created
		//
		ClassLoader cl = FileSystem.getFileSystem().getVfsClassLoader();
		Class<?> c = cl.loadClass(className);
		return c;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#destroy()
	 */
	public void destroy() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#exitValue()
	 */
	public int exitValue() {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#getErrorStream()
	 */
	public InputStream getErrorStream() {
		return err;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#getInputStream()
	 */
	public InputStream getInputStream() {
		return in;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#getOutputStream()
	 */
	public OutputStream getOutputStream() {
		return out;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Process#waitFor()
	 */
	public int waitFor() throws InterruptedException {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		try {
			/*
			 * try { AccessController.doPrivileged(new
			 * PrivilegedExceptionAction() { public Object run() throws
			 * Exception { return null; } }); } catch (PrivilegedActionException
			 * e) { throw (Exception) e.getException(); }
			 */
			Class<?> c = loadClass();
			Class<?>[] argTypes = new Class[] { String[].class };
			Method main = c.getDeclaredMethod("main", argTypes);
			main.invoke(null, new Object[] { args });
		} catch (Exception e) {
			//debug(e);
		}
	}

	
	public String[] getArgs() {
		return this.args;
	}

	public void setArgs(String[] args) {
		this.args = args;
	}

	public String getClassName() {
		return this.className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String[] getCmdarray() {
		return this.cmdarray;
	}

	public void setCmdarray(String[] cmdarray) {
		this.cmdarray = cmdarray;
	}

	public File getCwd() {
		return this.cwd;
	}

	public void setCwd(File cwd) {
		this.cwd = cwd;
	}

	public String[] getEnvp() {
		return this.envp;
	}

	public void setEnvp(String[] envp) {
		this.envp = envp;
	}

	public InputStream getErr() {
		return this.err;
	}

	public void setErr(InputStream err) {
		this.err = err;
	}

	public InputStream getIn() {
		return this.in;
	}

	public void setIn(InputStream in) {
		this.in = in;
	}

	public OutputStream getOut() {
		return this.out;
	}

	public void setOut(OutputStream out) {
		this.out = out;
	}

	/*
	 * 
	 */

//	private void debug(Object o) {
//			if (o instanceof Throwable) {
//				Log.log(Log.TRACE,this,o);
//				return;
//			}
//			Log.log(Log.DEBUG,this,o);
//	}
}
